
#include <string>

#include "storage.h"
#include "util.h"
#include "logger.h"
#include "ds_conf.h"
#include "globals.h"

#define DKFS_DATA_DIR_FMT "%02X"

int Storage::store_path_index = 0;

bool Storage::Init() {
  if (g_conf == NULL)
    return false;

  for (int i = 0; i < g_conf->data_paths.size(); i++) {
    const string &data_path = g_conf->data_paths[i]; 
    if (data_path.empty())
      continue;

    if (!MakeDataDir(data_path.c_str())) {
      return false;
    }
  }
  return true;
}

bool Storage::MakeDataDir(const char *data_path) {
  if (data_path == NULL)
    return false;

  if (!Util::FileExists(data_path)) {
    if (mkdir(data_path, 0755) != 0) {
      LOG_ERROR(__FILE__":%d mkdir %s fail: %s",
                __LINE__, data_path, strerror(errno));
      return false;
    }
  }

  if (chdir(data_path) != 0) {
    LOG_ERROR(__FILE__":%d chdir %s fail: %s",
              __LINE__, data_path, strerror(errno));
    return false;
  }

  int subdir_count_per_dir = g_conf->subdir_count_per_dir;
  char min_sub_dir[16];
  char max_sub_dir[16];
  sprintf(min_sub_dir, DKFS_DATA_DIR_FMT"/"DKFS_DATA_DIR_FMT, 0, 0); 
  sprintf(max_sub_dir, DKFS_DATA_DIR_FMT"/"DKFS_DATA_DIR_FMT,
          subdir_count_per_dir - 1, subdir_count_per_dir - 1);

  if (Util::FileExists(min_sub_dir) && Util::FileExists(max_sub_dir)) {
    return true;
  }

  fprintf(stderr, "data path:%s make subdir ...", data_path); 
  for (int i = 0; i < subdir_count_per_dir; i++) {
    char dir_name[9];
    char sub_name[9];

    sprintf(dir_name, DKFS_DATA_DIR_FMT, i);
    fprintf(stderr, "mkdir %s ...\n", dir_name);
    
    if (mkdir(dir_name, 0755) != 0) {
      if (!(errno == EEXIST && Util::IsDir(dir_name))) {
        LOG_ERROR("mkdir %s/%s fail: %s",
                  data_path, dir_name, strerror(errno));
        return false;
      }
    }

    if (chdir(dir_name) != 0) {
      LOG_ERROR(__FILE__":%d chdir %s/%s fail: %s",
                __LINE__, data_path, dir_name, strerror(errno));
      return false;
    }
    
    //To do, chown dir
    
    for (int j = 0; j < subdir_count_per_dir; j++) {
      sprintf(sub_name, DKFS_DATA_DIR_FMT, j);

      if (mkdir(sub_name, 0755) != 0) {
        if (!(errno == EEXIST && Util::IsDir(sub_name))) {
          LOG_ERROR("mkdir %s/%s/%s fail: %s",
                    data_path, dir_name, sub_name, strerror(errno));
          return false;
        }
      }

      //To do, chown dir
      
    } /* for */

    if (chdir("..") != 0) {
      LOG_ERROR(__FILE__":%d chdir %s fail: %s",
                __LINE__, data_path, strerror(errno));
      return false;
    }
  } /* for */

  fprintf(stderr, "mkdir %s, down\n", data_path);
  return true;
}
